Leading Hint是一个能指定超过一个表的多表Hint,Leading Hint指导优化器先按照Leading Hint指定的部分表的顺序进行Join,然后再将Join完成的表作为最先访问的表与剩余的其他表进行Join。
注意事项
目前暂未支持在嵌套SQL语句中使用Leading Hint,请勿在子类语句中使用Leading Hint,否则会产生不可预期的结果。
优化器在生成多表Join顺序时,对于有连接条件的表,会尽量先尝试与其有连接关系的表Join,如果这其中没有可以执行路径产生,才会去尝试生成Cartesian Product。因此,在使用Leading Hint时,对于有Join条件的表,紧跟着的表应尽可能是与前表有相关Join条件的表。否则,优化器会因为无法生成执行路径而忽略Leading Hint。
前提条件
PolarDB PostgreSQL版(兼容Oracle)默认开启支持Hints功能,可以执行以下命令开启该功能:
set enable_hints = true;
语法
Hints注释以
/*+
开始(*
和+
之间不能有空格),以*/
结束。提示语句包括提示名和接下来括号包含的参数,以空格作为分界。
需要紧跟在SELECT、UPDATE、INSERT、MERGE或DELETE关键字之后使用。
不区分Hints指令的大小写,即指令大写或小写形式都能正常工作。
出现以下情况时,会发生冲突,导致Leading Hint不生效。
当指定的表因为依赖关系等原因无法按照指示的顺序先进行Join时,会忽略掉Leading Hint。
当同时存在两个或多个Leading Hint时,会忽略掉所有的Leading Hint。
当Ordered Hint与Leading Hint同时存在时,Ordered Hint会覆盖掉所有Leading Hint。
当指定的表名或者别名中含有'.'时,例如,"s.t",会忽略掉Leading Hint。
没有紧跟在SELECT,UPDATE,INSERT,MERGE或DELETE关键字之后,会忽略掉Leading Hint。
示例
假设数据库中存在四张表, 四张表的表名或者别名为a b c d,且任意两表之间都可以进行连接。
正确的语法
示例
可能连接路径
/*+ leading(a) */
(((a b) c) d), (((a b) d) c), (((a c) b) d), (((a c) d) b), (((a d) b) c), (((a c) c) b)
/*+ leading(a b) */
(((a b) c) d), (((a b) d) c)
/*+ leading(a b c) */
(((a b) c) d)
/*+ leading(a b c d) */
(((a b) c) d)
说明((a b) c)
表示a b c三张表的Join顺序为a->b->c
,(c (a b))
表示a b c三张表的Join顺序为c->a->b
。错误的语法
示例如下所示:
/* + leading(a) */
/*+ leading(a b) leading(a b) */
/*+ leading(a b a) */
/*+ leading(a b) leading(a)*/
/*+ leading(a b) leading(c d) */
/*+ leading(a b e) */
*+ leading(a b) leading(a c) */
/*+ leading() */
说明数据库中不存在表名或别名为e的表。